// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose:  Definition of CXFormsManager class..
//   $Id$


#ifndef ___FP_XFORMS_MANAGER_H___
#define ___FP_XFORMS_MANAGER_H___

#include "XFormsXFormsElement.h"
#include "XForms.h"
#include "fp_returncodes.h"
#include "mustunderstand.h"
//#include "Config.h"
#include <Common/ImplReg/msw/ImplRegUtils.h>
#include "UpdateChecker.h"

#define MASK_32_BITS_SET 0xffffffff

class CXFormsManager
{
public:
	CXFormsManager();
	virtual ~CXFormsManager();
	CXFormsXFormsElement* GetForms(bool bStart = false);
	
	//<summary>Creates and returns a new form and adds it to the form list</summary>
	HRESULT GetForm(IHTMLDocument2 *pDoc2, CXFormsXFormsElement **ppForm);
	//<summary>Retrieves an existing form from the form list</summary>
	HRESULT GetForm(LONG lKey, CXFormsXFormsElement **ppForm);

	HRESULT getFormsDOM(IXMLDOMDocument **ppFormsDOM, bool bUseOmnipresentIds = false);
	HRESULT getModel(BSTR sFormId, BSTR sModelId, IXFormsModelElement **ppModel, bool bUseOmnipresentIds = false);
	HRESULT getControlsDOM(BSTR sFormId, IXMLDOMDocument **ppControlsDOM, bool bUseOmnipresentIds = false);
	HRESULT getControlInformationDOM(BSTR sFormId, BSTR sControlId, IXMLDOMDocument **ppControlInformationDOM, bool bUseOmnipresentIds = false);
	//<summary>
	// queries whether the processor can understand the given element.
	//</summary>
	HRESULT canUnderstandTag(BSTR bsNamespace,BSTR bsTagName,BOOL * pbCanUnderStand);
	HRESULT TestForRequiredComponents(bool bForce = false);
	inline CErrorInfoHelper& GetErrorSource(void)
	{
		if(!theErrorSource)
			theErrorSource = new CErrorInfoHelper(L"formsPlayer");
		return *theErrorSource;
	}
	// called when the app receives ExitInstance
	void onExitInstance(void);
	//<summary>
	//	Returns a pointer to the global schema cache.
	//</summary>
	HRESULT GetSchemaCache(IXMLDOMSchemaCollection** ppSchemaCache);

	// Return the directory that formsPlayer is installed in.
	HRESULT GetFPHomeDirectory(BSTR *lpbsFPHome) const;

	// Register formsPlayer for writing to the event log, if not already done so.
	HRESULT RegisterEventLog(void);

	// Write to the event log.
	HRESULT WriteEvent(WORD wType, DWORD dwEventId) const;

	// Generate complements of supplied arguments.
	inline unsigned long OnesComplement(const long l) const;
	inline unsigned long TwosComplement(const long l) const;

//	IConfigHandler* ConfigHandler(void);

	// Remove a form from the list of available forms.
	void removeForm(long pFormKey);

	// Bug 828: Allow dynamic invocation of Soft-Bars.
/*	inline HRESULT InvokeSoftbar(CXFormsXFormsElement *pXFXFEl, BSTR sSoftbarName, bool bNameIsId = false);
	inline HRESULT RevokeSoftbar(CXFormsXFormsElement *pXFXFEl, BSTR sSoftbarName, bool bNameIsId = false);

	HRESULT InvokeSystray(CXFormsXFormsElement *pXFXFEl, BSTR sConfigFile, ISysTrayIcon **ppIcon = 0);
	HRESULT InvokeSystrayStrict(CXFormsXFormsElement *pXFXFEl, BSTR sMenu, BSTR sTitle, BSTR sIcon, long nWidth, long nHeight, bool bAnimate, BSTR sAnimateDirection, long nAnimateTime, ISysTrayIcon **ppIcon = 0);
*/
	// Return the web browser object that an HTML document is "in".
	HRESULT GetBrowserFromDocument(IHTMLDocument2 *pDoc, IWebBrowser2 **ppWB2);

	// Return a pointer to the default system tray icon.
//	ISysTrayIcon *DefaultSystray(void);

	// Initialisation routine.
	HRESULT Initialise(BSTR sCurrentVersion);
/*
	// Increment system tray icon reference count.
	HRESULT SystrayAddref(void);

	// Decrement system tray icon reference count.
	HRESULT SystrayRelease(void);
*/
	// Globally-available DOM implementation registry pointer.
	CComPtr<IDOMImplementationRegistry> m_pDIR;

	HRESULT CreateDOMEvent(IDOMEvent** ppEvent);
	// Invoke the one-and-only default system tray icon.
	HRESULT InvokeDefaultSysTray(void);
	HRESULT GetDocImpl(IDOMImplementation** ppImpl);

	inline bool AreEventNotificationsEnabled(void) const throw();
	inline void SetEventNotificationState(bool bEnable) throw();

protected:
private:
	CComPtr<IClassFactory> m_pDOMEventFactory;
	POSITION m_pos;
	CComPtr<IXMLDOMDocument> m_pExposedInfoDOM;
	HRESULT CreateAndInitialiseFormsDOM(IXMLDOMNode **ppFormsNode);
	HRESULT InsertURLAttribute(IXMLDOMElement *pEl, CXFormsXFormsElement *pXXE);
	HRESULT InsertIdAttribute(IXMLDOMElement *pEl, CXFormsXFormsElement *pXXE, BSTR sId = 0);
	HRESULT InsertSrcidAttribute(IXMLDOMElement *pEl, BSTR sId);
	HRESULT InsertTypeAttribute(IXMLDOMElement *pEl, BSTR sType);
	HRESULT InsertModelsAndInstancesIntoFormsDOM(IXMLDOMElement *pEl, CXFormsXFormsElement *pXXE, bool bUseOmnipresentIds);
	HRESULT CreateAndInitialiseControlsDOM(IXMLDOMNode **ppControlsNode);
	HRESULT PopulateControlsDOM(CXFormsXFormsElement *pXFXFE, IXMLDOMNode *pControlsNode, bool bUseOmnipresentIds);
	HRESULT FindControl(BSTR sControlId, CXFormsXFormsElement *pXFXFE, const CFormControl **ppFC, bool bUseOmnipresentIds);
	HRESULT CreateAndInitialiseControlInfoDOM(const CFormControl *pFC, IXMLDOMDocument **ppXDE, bool bUseOmnipresentIds);
	HRESULT CreateModelForControlInfoDOM(IXMLDOMNode *pNodeCtrl, const CImplNodeBinding *pINB);
	HRESULT CreateRefOrNodesetForControlInfoDOM(IXMLDOMNode *pNodeCtrl, const CImplNodeBinding *pINB);
	HRESULT CreateFullXPathForControlInfoDOM(IXMLDOMNode *pNodeCtrl, const CImplNodeBinding *pINB);
	HRESULT CreateModelItemPropertiesForControlInfoDOM(IXMLDOMNode *pNodeCtrl, const CImplNodeBinding *pINB);

	void loadUnderstoodTags(void);
	void AddKnownTagsToNamespace(INamespace *pNS);

	//HRESULT InvokeOrRevokeSoftbar(CXFormsXFormsElement *pXFXFEl, BSTR sSoftbarName, bool bInvoke, bool bNameIsId);

	HRESULT GetNextFeature(BSTR &sFeatures, BSTR &sFeature, BSTR &sVersion);
	bool m_bCheckedRequiredComponents;
	CErrorInfoHelper * theErrorSource;

	//<value>stores the schemata loaded in loadGlobalSchemaCache</value>
	CComPtr<IXMLDOMSchemaCollection> m_pSchemaCache;

	//<summary>loads a schema each for xsd and xforms datatypes</summary>
	void loadGlobalSchemaCache(void);
	HRESULT AddToSchemaCache(BSTR sSchema, BSTR sNamespace);


	// Bug 284
	HANDLE m_hEvent;
	
	//bug 42
	CComPtr<IUnderstander> theUnderstander;
	//<summary>
	//	fetches the understander member, if it is NULL,
	//	creates a new one and initialises it with the default
	//	understood tags.
	//</summary>
	HRESULT GetUnderstander(IUnderstander** ppUnderstander);

	// Bug 374
//	CComQIPtr<IConfigHandler> m_pConfig;
	//<summary>
	//	storage of forms keyed on a long key
	//	TODO: use STL for better type control.
	//</summary>
	CMapPtrToPtr m_Forms;

	// The one-and-only default system tray icon.
//	CComQIPtr<ISysTrayIcon> m_pDefaultSysTrayIcon;

	// Initialisation flag.
	bool m_bInitialised;

	// System tray icon reference count.
	//long m_nSystrayRefCount;

	// Update checker.
	CUpdateChecker m_UpdateChecker;

	bool m_bEnableEventNotifications;
};

inline unsigned long CXFormsManager::OnesComplement(const long l) const
{
	return MASK_32_BITS_SET ^ l;
}

inline unsigned long CXFormsManager::TwosComplement(const long l) const
{
	return OnesComplement(l) + 1;
}
/*
// Bug 828: Allow dynamic invocation of Soft-Bars.
inline HRESULT CXFormsManager::InvokeSoftbar(CXFormsXFormsElement *pXFXFEl, BSTR sSoftbarName, bool bNameIsId)
{
	return InvokeOrRevokeSoftbar(pXFXFEl, sSoftbarName, true, bNameIsId);
}

inline HRESULT CXFormsManager::RevokeSoftbar(CXFormsXFormsElement *pXFXFEl, BSTR sSoftbarName, bool bNameIsId)
{
	return InvokeOrRevokeSoftbar(pXFXFEl, sSoftbarName, false, bNameIsId);
}
*/
inline bool CXFormsManager::AreEventNotificationsEnabled(void) const throw()
{
	return m_bEnableEventNotifications;
}

inline void CXFormsManager::SetEventNotificationState(bool bEnableEventNotifications) throw()
{
	m_bEnableEventNotifications = bEnableEventNotifications;
}

#endif
